﻿// 距离.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*

https://www.acwing.com/problem/content/1173/
http://ybt.ssoier.cn:8088/problem_show.php?pid=1552
给定一棵 n 个点的树，Q 个询问，每次询问点 x 到点 y 两点之间的距离。

【输入】
第一行一个正整数 n，表示这棵树有 n 个节点；

接下来 n−1 行，每行两个整数 x,y表示 x,y 之间有一条连边；

然后一个整数 Q，表示有 Q 个询问；

接下来 Q 行每行两个整数 x,y 表示询问 x 到 y 的距离。

【输出】
输出 Q 行，每行表示每个询问的答案。

【输入样例】
6
1 2
1 3
2 4
2 5
3 6
2
2 6
5 6
【输出样例】
3
4
【提示】
数据范围与提示：

对于全部数据，1≤n≤105,1≤x,y≤n
*/



#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int N = 100005;      // 最大节点数
const int M = 2 * N;       // 最大边数（无向边要乘2）

// 链式前向星存图相关数组
int head[N];               // head[u]表示u的第一条边的编号
int e[M];                 // to[i]表示第i条边的终点
int nxt[M];                // nxt[i]表示第i条边的下一条边的编号
int idx;                   // 边的总数（即当前可用的边的编号）

int n, Q;                  // n为节点数，Q为询问数
vector<pair<int, int>> query[N]; // 存每个点的所有询问，pair<另一个点, 询问编号>
int res[N];                // 存每个询问的答案
int dist[N];               // dist[i]表示i到根节点的距离
int p[N];                  // 并查集数组
int st[N];                 // 0:未访问, 1:正在访问, 2:已访问

// 并查集查找祖先
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

// 链式前向星加边函数（无向边要加两次）
void add(int a, int b) {
    e[idx] = b;           // 边的终点
    nxt[idx] = head[a];    // 下一条边指向原来的第一条边
    head[a] = idx++;       // 更新第一条边为当前边
}

// 预处理每个点到根的距离
void dfs(int u, int fa) {
    for (int i = head[u]; i != -1; i = nxt[i]) { // 遍历u的所有邻接点
        int v = e[i];
        if (v == fa) continue;                   // 跳过父节点，防止回头
        dist[v] = dist[u] + 1;                   // 距离加1
        dfs(v, u);                               // 递归处理子节点
    }
}

// Tarjan离线LCA算法
void tarjan(int u) {
    st[u] = 1;                                   // 标记u正在访问
    for (int i = head[u]; i != -1; i = nxt[i]) { // 遍历u的所有邻接点
        int v = e[i];
        if (!st[v]) {                            // 只访问未访问过的子节点
            tarjan(v);                           // 递归访问
            p[v] = u;                            // 回溯时将子节点的祖先设为当前节点
        }
    }
    // 处理所有以u为端点的询问
    for (auto& q : query[u]) {
        int y = q.first, id = q.second;
        if (st[y] == 2) {                        // 另一个点已访问完
            int anc = find(y);                   // 查询LCA
            res[id] = dist[u] + dist[y] - 2 * dist[anc]; // 距离公式
        }
    }
    st[u] = 2;                                   // 标记u访问完成
}

int main() {
    scanf("%d", &n);
    memset(head, -1, sizeof head);               // 初始化head数组为-1
    idx = 0;                                     // 初始化边的编号
    for (int i = 1; i < n; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);                               // 加边（无向边要加两次）
        add(b, a);
    }
    scanf("%d", &Q);
    for (int i = 0; i < Q; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a != b) {
            query[a].push_back({ b, i });        // 双向存储询问
            query[b].push_back({ a, i });
        }
    }
    for (int i = 1; i <= n; i++) p[i] = i;       // 初始化并查集
    memset(st, 0, sizeof st);                    // 初始化状态数组
    dist[1] = 0;                                 // 根节点距离为0
    dfs(1, -1);                                  // 预处理距离
    tarjan(1);                                   // 求LCA并回答所有询问
    for (int i = 0; i < Q; i++) {
        printf("%d\n", res[i]);                  // 输出答案
    }
    return 0;
}